package tagdb.ui.filter;

import tagdb.denovo.DenovoHit;
import tagdb.io.MascotGenericFile;

import java.util.*;

/**
 * This filter is applied when search specific spectra / peptides etc. from
 * the de novo results.
 *
 * @author Thilo Muth
 * @version 0.5.3
 * @date 02-12-2013
 */
public class DenovoSearchFilter {

    /**
     * Peptide sequence.
     */
    private String peptideSequence;

    /**
     * Tag sequence.
     */
    private String tagSequence;

    /**
     * Score threshold.
     */
    private double scoreThreshold = -1.0;

    /**
     * Spectrum title.
     */
    private String spectrumTitle;

    /**
     * The unfiltered spectra.
     */
    private List<MascotGenericFile> unfilteredSpectra;

    /**
     * The filtered spectra.
     */
    private Set<MascotGenericFile> filteredSpectra;

    /**
     * The denovo hit results.
     */
    private Map<String, List<DenovoHit>> resultsMap;


    /**
     * This method filters the de novo search results by their peptide sequences.
     */
    private void filterByPeptideSequence() {

        filteredSpectra = new HashSet<MascotGenericFile>();
        if (peptideSequence != null && !peptideSequence.equals("")) {

            for (MascotGenericFile mgf : unfilteredSpectra) {
                String spectrumTitle = mgf.getTitle();

                if (resultsMap.containsKey(spectrumTitle)) {
                    List<DenovoHit> pepnovoList = resultsMap.get(spectrumTitle);
                    for (int i = 0; i < pepnovoList.size(); i++) {
                        DenovoHit hit = pepnovoList.get(i);
                        if (hit.getSequence().equalsIgnoreCase(peptideSequence)) {
                            filteredSpectra.add(mgf);
                        }
                    }
                }
            }
        }
    }

    /**
     * This method filters the de novo search results by their score.
     */
    private void filterByPeptideScore() {
        filteredSpectra = new HashSet<MascotGenericFile>();

        for (MascotGenericFile mgf : unfilteredSpectra) {
            String spectrumTitle = mgf.getTitle();

            if (resultsMap.containsKey(spectrumTitle)) {
                List<DenovoHit> pepnovoList = resultsMap.get(spectrumTitle);
                for (int i = 0; i < pepnovoList.size(); i++) {
                    DenovoHit hit = pepnovoList.get(i);
                    if (hit.getPepNovoScore() >= scoreThreshold) {
                        filteredSpectra.add(mgf);
                    }
                }
            }
        }

    }

    /**
     * This method filters the de novo search results by their score.
     */
    private void filterBySpectrumTitle() {
        filteredSpectra = new HashSet<MascotGenericFile>();
        if (spectrumTitle != null && !spectrumTitle.equals("")) {
            for (MascotGenericFile mgf : unfilteredSpectra) {
                String queryTitle = mgf.getTitle();
                if(queryTitle.equals(spectrumTitle)) {
                    filteredSpectra.add(mgf);
                }
            }
        }
    }

    /**
     * Returns the filtered spectra.
     *
     * @return The filtered spectra
     */
    public List<MascotGenericFile> getFilteredSpectra() {
        applyFilter();
        return new ArrayList<MascotGenericFile>(filteredSpectra);
    }

    /**
     * This method applies the corresponding filter, depending on which filtering was chosen first.
     */
    private void applyFilter() {
        if(peptideSequence != null && !peptideSequence.equals("")) {
            filterByPeptideSequence();
        }
        if(spectrumTitle != null && !spectrumTitle.equals("")) {
            filterBySpectrumTitle();
        }
        if(scoreThreshold >= 0.0) {
            filterByPeptideScore();
        }
    }
    /**
     * Sets the original -unfiltered- spectra.
     *
     * @param unfilteredSpectra Unfiltered spectra
     */
    public void setUnfilteredSpectra(List<MascotGenericFile> unfilteredSpectra) {
        this.unfilteredSpectra = unfilteredSpectra;
    }

    /**
     * Sets the de novo results map.
     *
     * @param resultsMap De novo results map
     */
    public void setResultsMap(Map<String, List<DenovoHit>> resultsMap) {
        this.resultsMap = resultsMap;
    }

    /**
     * Sets the peptide sequence filter.
     *
     * @param peptideSequence Peptide sequence to be filtered.
     */
    public void setPeptideSequence(String peptideSequence) {
        this.peptideSequence = peptideSequence;

    }

    /**
     * Gets the current peptide sequence filter.
     * @return Peptide sequence filter
     */
    public String getPeptideSequence() {
        return peptideSequence;
    }

    /**
     * Returns the current score threshold filter.
     * @return Score threshold filter
     */
    public double getScoreThreshold() {
        return scoreThreshold;
    }

    /**
     * Returns the tag sequence filter.
     * @return Tag sequence filter.
     */
    public String getTagSequence() {
        return tagSequence;
    }

    /**
     * Returns the current spectrum title filter.
     * @return Spectrum title filter.
     */
    public String getSpectrumTitle() {
        return spectrumTitle;
    }
}
